/**
 * 
 */
package org.apache.cordova.api;

import javafx.application.Platform;
import javafx.scene.web.PromptData;
import javafx.scene.web.WebEngine;
import javafx.scene.web.WebView;
import javafx.util.Callback;

import com.googlecode.jfxgap.DesktopCordovaContext;
import com.googlecode.jfxgap.JavaFxCordovaApp;

/**
 * @author popom
 *
 */
public class CordovaWebView {

	private static final String CORDOVA_EXEC_URL_PREFIX = "http://cdv_exec/";

	private WebView view;

	private boolean finished;

	private DesktopCordovaContext cordovaContext;

	private PluginManager pluginManager;

	public CordovaWebView(JavaFxCordovaApp javaFxCordovaApp) {
		this.view = javaFxCordovaApp.getWebView();

        final WebEngine webEngine = javaFxCordovaApp.getWebView().getEngine();
        webEngine.setPromptHandler(new Callback<PromptData, String>() {
            public String call(PromptData promptData) {
                System.out.println("PROMPT: "+ promptData.getMessage());
            	handleExecUrl(promptData.getMessage());
                return null;
            }
        });

        cordovaContext = new DesktopCordovaContext(javaFxCordovaApp);
		pluginManager = new PluginManager(this, cordovaContext);
		pluginManager.init();
	}

    // Parses commands sent by setting the webView's URL to:
    // cdvbrg:service/action/callbackId#jsonArgs
	private void handleExecUrl(String url) {
		//int idx1 = CORDOVA_EXEC_URL_PREFIX.length();
		int idx1 = -1;
		int idx2 = url.indexOf('/', idx1 + 1);
		int idx3 = url.indexOf('/', idx2 + 1);
		int idx4 = url.indexOf('/', idx3 + 1);
		if (idx1 == 0 || idx2 == -1 || idx3 == -1 || idx4 == -1) {
			System.err.println("Could not decode URL command: " + url);
			return;
		}
		String service    = url.substring(idx1 + 1, idx2);
		String action     = url.substring(idx2 + 1, idx3);
		String callbackId = url.substring(idx3 + 1, idx4);
		String jsonArgs   = url.substring(idx4 + 1);
        pluginManager.exec(service, action, callbackId, jsonArgs);
	}

	/**
	 * @return the view
	 */
	public WebView getView() {
		return view;
	}

	/**
	 * @return the finished
	 */
	public boolean isFinished() {
		return finished;
	}

	public void sendPluginResult(final PluginResult pluginResult, final String callbackId) {
		// JavaFX Thread runnable object
		Runnable runnablePluginResult = new Runnable() {
			
			@Override
			public void run() {
				System.out.println(">> sendPluginResult ..." + this);
		        synchronized (this) {
		            if (finished) {
		            	// FIXME CJO
		                System.out.println(" - Attempted to send a second callback for ID: " + callbackId + "\nResult was: " + pluginResult.getMessage());
		                //return;
		            } else {
		                finished = !pluginResult.getKeepCallback();
		            }
		        }

		        // Create plugin result javascript exec
		        String pluginResultJs = pluginResult.toCallbackString(callbackId);
		        System.out.println("pluginResultJs: " + pluginResultJs);
				// Send javascript 
		        view.getEngine().executeScript(pluginResultJs);
		        System.out.println("<< sendPluginResult ...");				
			}
		};

		// Be sure to execute plugin result on JavaFX Thread
		Platform.runLater(runnablePluginResult);
	}

	public void postMessage(String id, String data) {
		pluginManager.postMessage(id, data);
	}
}
